/*
 ============================================================================
 Name       : Log.cpp
 Author   : 
 Version     : 1.0
 Copyright   : 
 Description : CLog implementation
 ============================================================================
 */

#include "Log.h"

#include <f32file.h>
#include <utf.h>
#include <e32std.h>
 
// Yes, this is fugly, but only for testing

#define GET_INSTANCE() static_cast<CLog*>(Dll::Tls())
#define SET_INSTANCE(ptr) User::LeaveIfError( Dll::SetTls(static_cast<TAny*>(ptr)) )

CLog::CLog( RFs& aFs, const TDesC& aFileName )
    : iFs( aFs )
    {
    iLogFileName.Copy( aFileName );
    }

CLog::~CLog()
    {
    iBuffer.Close();
    iBuffer16.Close();
    SET_INSTANCE(NULL);
    }

CLog* CLog::NewLC( RFs& aFs, const TDesC& aFileName )
    {
    CLog* self = new (ELeave) CLog( aFs, aFileName );
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

CLog* CLog::NewL( RFs& aFs, const TDesC& aFileName )
    {
    CLog* self = CLog::NewLC( aFs, aFileName );
    CleanupStack::Pop(self);
    return self;
    }

void CLog::ConstructL()
    {
    if ( GET_INSTANCE() )
        {
        User::Leave( KErrAlreadyExists );
        }
    SET_INSTANCE(this);
    iBuffer.CreateL( 16 * 1024 );
    iBuffer16.CreateL( 16 * 1024 );
#ifdef LOGGING
    RFile log;
    log.Replace( iFs, iLogFileName, EFileWrite );
    log.Close();
#endif
    }

void CLog::Delete()
    {
    delete GET_INSTANCE();
    SET_INSTANCE(NULL);
    }

void CLog::Log( TRefByValue< const TDesC8 > aFormat, ... )
    {
    VA_LIST va;
    VA_START( va, aFormat );
    TRAP_IGNORE( GET_INSTANCE()->DoLogL( aFormat, va ) );
    VA_END( va );
    }

void CLog::Log( TRefByValue< const TDesC > aFormat, ... )
    {
    VA_LIST va;
    VA_START( va, aFormat );
    TRAP_IGNORE( GET_INSTANCE()->DoLogL( aFormat, va ) );
    VA_END( va );
    }

_LIT8( KNewLine, "\r\n" );

void CLog::DoLogL( TRefByValue< const TDesC > aFormat, VA_LIST aVarArgList )
    {
    RFile log;
    User::LeaveIfError( log.Open( iFs, iLogFileName, EFileWrite ) );
    TInt pos = 0;
    log.Seek( ESeekEnd, pos );
    iBuffer16.FormatList( aFormat, aVarArgList );
    iBuffer.Zero();
    CnvUtfConverter::ConvertFromUnicodeToUtf8( iBuffer, iBuffer16 );
    log.Write( iBuffer );
    log.Write( KNewLine() );
    log.Close();
    }

void CLog::DoLogL( TRefByValue< const TDesC8 > aFormat, VA_LIST aVarArgList )
    {
    RFile log;
    User::LeaveIfError( log.Open( iFs, iLogFileName, EFileWrite ) );
    TInt pos = 0;
    log.Seek( ESeekEnd, pos );
    iBuffer.FormatList( aFormat, aVarArgList );
    log.Write( iBuffer );
    log.Write( KNewLine() );
    log.Close();
    }

